package com.cxria.problem.conf

import com.cxria.problem.security.handler.*
import com.cxria.problem.service.impl.UserServiceImpl
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.AuthenticationEntryPoint
import org.springframework.security.web.access.AccessDeniedHandler
import org.springframework.security.web.authentication.AuthenticationFailureHandler
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler

@Configuration
//@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConf extends WebSecurityConfigurerAdapter{

    @Bean
    UserDetailsService userService(){
        new UserServiceImpl()
    }

    @Bean
    AuthenticationEntryPoint authenticationEntryPoint(){
        new AuthEntryPoint()
    }

    @Bean
    AuthenticationSuccessHandler authenticationSuccessHandler() {
        new AuthSuccessHandler()
    }

    @Bean
    AuthenticationFailureHandler authenticationFailureHandler(){
        new AuthFailureHandler()
    }

    @Bean
    AccessDeniedHandler accessDeniedHandler(){
        new AuthAccessDeniedHandler()
    }

    @Bean
    LogoutSuccessHandler logoutSuccessHandler(){
        new AuthLogoutSuccessHandler()
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        new BCryptPasswordEncoder()
    }

    @Override
    void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService())
                .passwordEncoder(passwordEncoder())
    }

    @Override
    void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                    .antMatchers('/user/regist').permitAll()
                    .antMatchers('/user/list', '/user/*/show').hasAuthority('用户查看')
                    .antMatchers('/user/*/delete').hasAuthority('用户封禁')
                    .antMatchers('/user/update/password').authenticated()
                    .anyRequest().authenticated()
                .and().formLogin()
                    .loginPage('/user/login')
                    .usernameParameter('username')
                    .passwordParameter('password')
                    .successHandler(authenticationSuccessHandler())
                    .failureHandler(authenticationFailureHandler())
                    .permitAll()
                .and().logout()
                    .logoutUrl('/user/logout')
                    .logoutSuccessHandler(logoutSuccessHandler())
                    .permitAll()
                .and().exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint())
                    .accessDeniedHandler(accessDeniedHandler())
    }

    @Override
    void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                '/css/**',
                '/swagger-ui.html',
                '/webjars/springfox-swagger-ui/**',
                '/swagger-resources/**',
                '/v2/api-docs',
                '/'
        )
    }

}
